source("./Mean Reversion/RMR.010 Cross Validate Functions.R")pricing_data <- read_csv("./Mean Reversion/Raw Data/pricing data.csv", col_types = c("iTdddddddci")) %>%
filter(date_time < "2017-10-09")Description
A list of parameters passed to the functions below that describe the mean reversion pairs trading strategy.
Arguments
time_resolution: The number of seconds that each observation spans. Takes values 300, 900, 1800, 7200, 14400, and 86400.
quote_currency: A string indicating the quote currency of the currency pairs. Takes values “USDT” or “BTC”.
cointegration_test: A string indicating whether the Engle-Granger method or distance method is used to test for cointegration. Takes values “eg” or “distance”.
adf_threshold: The threshold for the ADF test statistic. Pairs below this threshold are selected when using the Engle-Granger method.
distance_threshold: The number of coin pairs to select when using the distance method.
train_window: A lubridate period object representing the length of time the train set covers.
test_window: A lubridate period object representing the length of time the the test set covers.
model_type: A string indicating whether raw prices or log prices should be used. Takes value “raw” or “log”.
spread_type: A string indicating whether the regression uses a rolling or fixed window. Takes value “rolling” or “fixed”.
rolling_window: The number of observations used in each window of a rolling linear regression.
signal_logic: A string indicating which logic to use to generate signals. Takes values “scaled” or “discrete”.
signal_scaled_enter: The z-score threshold indicating the z-score that the signal is fully scaled in when the signal logic is scaled.
signal_discrete_enter: The z-score threshold for entering a position when the signal logic is discrete.
signal_discrete_exit: The z-score threshold for exiting a position when the signal logic is discrete.
signal_stop: A threshold for the spread z-score beyond which the strategy stops trading the coin pair.
signal_reenter: A boolean indicating whether the strategy should reenter positions after exceeding the signal_stop threshold once the spread z-score returns to a reasonable range.
signal_reenter_threshold: The z-score threshold for reentering a position if signal_reenter is TRUE. pair_allocation: A string indicating whether the capital allocation to the coin pairs should be equal or weighted. Takes values “equal”, “weighted”, and “scaled”.
pair_allocation_scaling: A double indicating the volatility scaling applied to the cointegration stat when the pair allocation is scaled.
params <- list(time_resolution = 300,
quote_currency = "USDT",
cointegration_test = "eg",
adf_threshold = -3.55,
distance_threshold = 0.40,
train_window = days(25),
test_window = days(20),
model_type = "raw",
spread_type = "rolling",
rolling_window = 576,
signal_logic = "scaled",
signal_scaled_enter = 4.0,
signal_discrete_enter = 1.15,
signal_discrete_exit = 0.05,
signal_stop = 5.55,
signal_reenter = TRUE,
signal_reenter_threshold = 0.85,
pair_allocation = "equal",
pair_allocation_scaling = 1.25)
number_pairs <- 8 plot_many(pricing_data = pricing_data,
cutoff_date = "2017-09-01",
params = params,
number_pairs = number_pairs)## # A tibble: 8 x 3
## coin_y coin_x cointegration_stat
## <chr> <chr> <dbl>
## 1 USDT_REP USDT_ZEC -5.141424
## 2 USDT_ZEC USDT_REP -4.809243
## 3 USDT_REP USDT_XMR -4.285768
## 4 USDT_ETH USDT_LTC -3.966150
## 5 USDT_ZEC USDT_XMR -3.800334
## 6 USDT_ZEC USDT_LTC -3.719053
## 7 USDT_ZEC USDT_ETH -3.579106
## 8 USDT_REP USDT_DASH -3.554924
plot_many(pricing_data = pricing_data,
cutoff_date = "2017-08-01",
params = params,
number_pairs = number_pairs)## # A tibble: 15 x 3
## coin_y coin_x cointegration_stat
## <chr> <chr> <dbl>
## 1 USDT_XMR USDT_DASH -5.518874
## 2 USDT_DASH USDT_XMR -5.394223
## 3 USDT_ETH USDT_ZEC -5.246258
## 4 USDT_ZEC USDT_ETH -5.215597
## 5 USDT_REP USDT_ZEC -5.175159
## 6 USDT_LTC USDT_ZEC -4.973607
## 7 USDT_ZEC USDT_REP -4.832974
## 8 USDT_ZEC USDT_LTC -4.706494
## 9 USDT_REP USDT_ETH -4.500360
## 10 USDT_REP USDT_LTC -4.427595
## 11 USDT_LTC USDT_REP -4.328207
## 12 USDT_ETH USDT_REP -4.151579
## 13 USDT_LTC USDT_ETH -4.019195
## 14 USDT_ETH USDT_LTC -3.743634
## 15 USDT_ETH USDT_DASH -3.694956
plot_many(pricing_data = pricing_data,
cutoff_date = "2017-07-01",
params = params,
number_pairs = number_pairs)## # A tibble: 8 x 3
## coin_y coin_x cointegration_stat
## <chr> <chr> <dbl>
## 1 USDT_REP USDT_XMR -8.970894
## 2 USDT_XMR USDT_REP -8.755381
## 3 USDT_REP USDT_BTC -5.526647
## 4 USDT_BTC USDT_XMR -5.495315
## 5 USDT_XMR USDT_BTC -5.449966
## 6 USDT_BTC USDT_REP -5.238047
## 7 USDT_DASH USDT_LTC -3.844027
## 8 USDT_DASH USDT_ZEC -3.607634
plot_many(pricing_data = pricing_data,
cutoff_date = "2017-06-01",
params = params,
number_pairs = number_pairs)## # A tibble: 25 x 3
## coin_y coin_x cointegration_stat
## <chr> <chr> <dbl>
## 1 USDT_REP USDT_XMR -8.148188
## 2 USDT_XMR USDT_REP -7.990751
## 3 USDT_XMR USDT_DASH -7.536854
## 4 USDT_REP USDT_DASH -7.533585
## 5 USDT_DASH USDT_XMR -7.508361
## 6 USDT_DASH USDT_REP -7.338676
## 7 USDT_REP USDT_ZEC -6.075070
## 8 USDT_DASH USDT_ZEC -5.898254
## 9 USDT_ZEC USDT_DASH -5.733057
## 10 USDT_ZEC USDT_REP -5.662455
## # ... with 15 more rows
plot_many(pricing_data = pricing_data,
cutoff_date = "2017-05-01",
params = params,
number_pairs = number_pairs)## # A tibble: 17 x 3
## coin_y coin_x cointegration_stat
## <chr> <chr> <dbl>
## 1 USDT_ZEC USDT_DASH -5.223039
## 2 USDT_DASH USDT_ZEC -5.188361
## 3 USDT_REP USDT_DASH -4.789840
## 4 USDT_DASH USDT_REP -4.769153
## 5 USDT_ZEC USDT_REP -4.628554
## 6 USDT_REP USDT_ZEC -4.618243
## 7 USDT_XMR USDT_ZEC -4.336148
## 8 USDT_ZEC USDT_ETH -4.294953
## 9 USDT_XMR USDT_ETH -4.274989
## 10 USDT_DASH USDT_ETH -4.169103
## 11 USDT_REP USDT_ETH -4.163347
## 12 USDT_ZEC USDT_XMR -3.976505
## 13 USDT_ETH USDT_ZEC -3.801298
## 14 USDT_XMR USDT_DASH -3.734803
## 15 USDT_ETH USDT_DASH -3.679363
## 16 USDT_ETH USDT_REP -3.656884
## 17 USDT_BTC USDT_LTC -3.611149
plot_many(pricing_data = pricing_data,
cutoff_date = "2017-04-01",
params = params,
number_pairs = number_pairs)## # A tibble: 8 x 3
## coin_y coin_x cointegration_stat
## <chr> <chr> <dbl>
## 1 USDT_DASH USDT_XMR -4.551650
## 2 USDT_XMR USDT_DASH -4.519761
## 3 USDT_BTC USDT_ZEC -4.414520
## 4 USDT_ZEC USDT_BTC -4.302815
## 5 USDT_ZEC USDT_XMR -4.014570
## 6 USDT_XMR USDT_ZEC -3.987019
## 7 USDT_REP USDT_ETH -3.804929
## 8 USDT_ETH USDT_REP -3.583538
plot_many(pricing_data = pricing_data,
cutoff_date = "2017-03-01",
params = params,
number_pairs = number_pairs)## # A tibble: 11 x 3
## coin_y coin_x cointegration_stat
## <chr> <chr> <dbl>
## 1 USDT_LTC USDT_ZEC -5.133481
## 2 USDT_LTC USDT_XMR -5.090589
## 3 USDT_LTC USDT_BTC -5.072744
## 4 USDT_LTC USDT_REP -4.941091
## 5 USDT_LTC USDT_ETH -4.928465
## 6 USDT_LTC USDT_DASH -4.924740
## 7 USDT_ETH USDT_DASH -3.756945
## 8 USDT_XMR USDT_REP -3.692843
## 9 USDT_DASH USDT_ETH -3.688327
## 10 USDT_XMR USDT_BTC -3.565989
## 11 USDT_XMR USDT_LTC -3.550346
plot_many(pricing_data = pricing_data,
cutoff_date = "2017-02-01",
params = params,
number_pairs = number_pairs)## # A tibble: 16 x 3
## coin_y coin_x cointegration_stat
## <chr> <chr> <dbl>
## 1 USDT_ETH USDT_BTC -5.880738
## 2 USDT_REP USDT_ETH -5.581765
## 3 USDT_REP USDT_BTC -5.551202
## 4 USDT_BTC USDT_ETH -5.414703
## 5 USDT_REP USDT_DASH -5.188077
## 6 USDT_REP USDT_LTC -4.689989
## 7 USDT_REP USDT_ZEC -4.646311
## 8 USDT_REP USDT_XMR -4.559337
## 9 USDT_ETH USDT_DASH -4.305797
## 10 USDT_ETH USDT_REP -4.065880
## 11 USDT_XMR USDT_LTC -3.891866
## 12 USDT_LTC USDT_XMR -3.839808
## 13 USDT_XMR USDT_BTC -3.819065
## 14 USDT_XMR USDT_ETH -3.753039
## 15 USDT_ZEC USDT_DASH -3.657396
## 16 USDT_DASH USDT_ETH -3.566371
plot_many(pricing_data = pricing_data,
cutoff_date = "2017-01-01",
params = params,
number_pairs = number_pairs)## # A tibble: 9 x 3
## coin_y coin_x cointegration_stat
## <chr> <chr> <dbl>
## 1 USDT_REP USDT_XMR -5.387352
## 2 USDT_REP USDT_ETH -4.584551
## 3 USDT_REP USDT_DASH -4.545369
## 4 USDT_REP USDT_BTC -4.471198
## 5 USDT_REP USDT_LTC -4.455255
## 6 USDT_REP USDT_ZEC -4.428392
## 7 USDT_LTC USDT_BTC -4.139843
## 8 USDT_BTC USDT_LTC -3.790503
## 9 USDT_DASH USDT_XMR -3.564016
results <- backtest_strategy_full(pricing_data = pricing_data,
params = params) ## [1] "Cross validating strategy."
## [1] "Using train set from 2016-12-07 to 2017-01-01."
## [1] "Using test set from 2017-01-01 to 2017-01-21."
## [1] "Cross validating strategy."
## [1] "Using train set from 2016-12-27 to 2017-01-21."
## [1] "Using test set from 2017-01-21 to 2017-02-10."
## [1] "Cross validating strategy."
## [1] "Using train set from 2017-01-16 to 2017-02-10."
## [1] "Using test set from 2017-02-10 to 2017-03-02."
## [1] "Cross validating strategy."
## [1] "Using train set from 2017-02-05 to 2017-03-02."
## [1] "Using test set from 2017-03-02 to 2017-03-22."
## [1] "Cross validating strategy."
## [1] "Using train set from 2017-02-25 to 2017-03-22."
## [1] "Using test set from 2017-03-22 to 2017-04-11."
## [1] "Cross validating strategy."
## [1] "Using train set from 2017-03-17 to 2017-04-11."
## [1] "Using test set from 2017-04-11 to 2017-05-01."
## [1] "Cross validating strategy."
## [1] "Using train set from 2017-04-06 to 2017-05-01."
## [1] "Using test set from 2017-05-01 to 2017-05-21."
## [1] "Cross validating strategy."
## [1] "Using train set from 2017-04-26 to 2017-05-21."
## [1] "Using test set from 2017-05-21 to 2017-06-10."
## [1] "Cross validating strategy."
## [1] "Using train set from 2017-05-16 to 2017-06-10."
## [1] "Using test set from 2017-06-10 to 2017-06-30."
## [1] "Cross validating strategy."
## [1] "Using train set from 2017-06-05 to 2017-06-30."
## [1] "Using test set from 2017-06-30 to 2017-07-20."
## [1] "Cross validating strategy."
## [1] "Using train set from 2017-06-25 to 2017-07-20."
## [1] "Using test set from 2017-07-20 to 2017-08-09."
## [1] "Cross validating strategy."
## [1] "Using train set from 2017-07-15 to 2017-08-09."
## [1] "Using test set from 2017-08-09 to 2017-08-29."
## [1] "Cross validating strategy."
## [1] "Using train set from 2017-08-04 to 2017-08-29."
## [1] "Using test set from 2017-08-29 to 2017-09-18."
## [1] "Cross validating strategy."
## [1] "Using train set from 2017-08-24 to 2017-09-18."
## [1] "Using test set from 2017-09-18 to 2017-10-08."
ggplot(results, aes(x = date_time)) +
geom_line(aes(y = return_strategy_cumulative), colour = "blue", size = 1) +
geom_hline(yintercept = 1, colour = "black") +
labs(title = "Strategy Return vs Buy Hold Return", x = "Date", y = "Cumulative Return") print(results[["return_strategy_cumulative"]][nrow(results)]) ## [1] 890.4977